package com.dm.voicesubtitle.audio;

import com.dm.voicesubtitle.config.AppConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sound.sampled.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 音频捕获类
 */
public class AudioCapture {
    private static final Logger logger = LoggerFactory.getLogger(AudioCapture.class);
    
    private TargetDataLine audioLine;
    private AudioFormat audioFormat;
    private final AtomicBoolean isRecording;
    private final AudioDataListener dataListener;
    private Thread captureThread;
    
    public AudioCapture(AudioDataListener dataListener) {
        this.dataListener = dataListener;
        this.isRecording = new AtomicBoolean(false);
        initializeAudioFormat();
    }
    
    /**
     * 初始化音频格式
     */
    private void initializeAudioFormat() {
        AppConfig.AudioConfig config = AppConfig.getInstance().getAudioConfig();
        this.audioFormat = new AudioFormat(
            config.getSampleRate(),
            config.getBitsPerSample(),
            config.getChannels(),
            true, // signed
            false // little endian
        );
        logger.info("音频格式初始化: {}", audioFormat);
    }
    
    /**
     * 开始录音
     */
    public void startRecording() {
        if (isRecording.get()) {
            logger.warn("录音已在进行中");
            return;
        }
        
        try {
            DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
            
            if (!AudioSystem.isLineSupported(info)) {
                throw new LineUnavailableException("不支持的音频格式: " + audioFormat);
            }
            
            audioLine = (TargetDataLine) AudioSystem.getLine(info);
            audioLine.open(audioFormat);
            audioLine.start();
            
            isRecording.set(true);
            captureThread = new Thread(this::captureAudio);
            captureThread.start();
            
            logger.info("开始录音");
            
        } catch (LineUnavailableException e) {
            logger.error("无法启动录音", e);
            throw new RuntimeException("录音启动失败", e);
        }
    }
    
    /**
     * 停止录音
     */
    public void stopRecording() {
        if (!isRecording.get()) {
            logger.warn("录音未在进行中");
            return;
        }
        
        isRecording.set(false);
        
        if (captureThread != null) {
            captureThread.interrupt();
            try {
                captureThread.join(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        if (audioLine != null) {
            audioLine.stop();
            audioLine.close();
        }
        
        logger.info("录音已停止");
    }
    
    /**
     * 音频捕获线程
     */
    private void captureAudio() {
        byte[] buffer = new byte[4096];
        ByteArrayOutputStream audioData = new ByteArrayOutputStream();
        
        try {
            while (isRecording.get() && !Thread.currentThread().isInterrupted()) {
                int count = audioLine.read(buffer, 0, buffer.length);
                if (count > 0) {
                    audioData.write(buffer, 0, count);
                    
                    // 当累积足够的数据时，发送给监听器
                    if (audioData.size() >= 3200) { // 约200ms的音频数据
                        byte[] data = audioData.toByteArray();
                        if (dataListener != null) {
                            dataListener.onAudioData(data, audioFormat);
                        }
                        audioData.reset();
                    }
                }
            }
        } catch (Exception e) {
            logger.error("音频捕获过程中发生错误", e);
        }
    }
    
    /**
     * 获取可用的音频输入设备
     */
    public static Mixer.Info[] getAvailableAudioInputs() {
        return AudioSystem.getMixerInfo();
    }
    
    /**
     * 检查是否正在录音
     */
    public boolean isRecording() {
        return isRecording.get();
    }
    
    /**
     * 音频数据监听器接口
     */
    public interface AudioDataListener {
        void onAudioData(byte[] audioData, AudioFormat format);
    }
} 